import java.util.ArrayList;


// OthelloAI.java
//
// ICS 23 / CSE 23 Fall 2007
// Project #2: Black and White
//
// Your AI should be implemented in a class that implements this OthelloAI
// interface.  Remember that your AI class needs to follow a specific
// naming convention.  It should be called "OthelloAI[yourID#]".  So, if
// your student ID# is 12345678, your AI class should be called
// "OthelloAI12345678".  Naturally, you should write that class in a file
// called "OthelloAI12345678.java".


public class OthelloAI3196901 implements OthelloAI{

	final static int GRID_XY_LENGTH = 8;
	final static int DEPTH = 4;
	boolean isBlackPlayer;
	// chooseMove() takes an OthelloGameState and chooses the best move,
	// returning an OthelloMove that indicates what the move is.  For
	// example, if the appropriate move is to place a tile in row 0 column 3,
	// you'd return a new OthelloMove with row 0 and column 3.


	ArrayList<OthelloMove> getValidMoves(OthelloGameState state){
		ArrayList<OthelloMove>  validMoves = new ArrayList<OthelloMove>();
		for(int y = 0; y < GRID_XY_LENGTH; ++y){
			for(int x = 0; x < GRID_XY_LENGTH; ++x){
				if(state.isValidMove(y, x)){

					validMoves.add(new OthelloMove(y, x));
				}
			}
		}
		return validMoves;
	}
	int eval(OthelloGameState state){
		return
			isBlackPlayer?
				state.getBlackScore() - state.getWhiteScore():
				state.getWhiteScore() - state.getBlackScore();
	}

	int search(OthelloGameState state, int depth){
		if(depth == 0){
			return eval(state);
		}
		else{
			if(state.isBlackTurn() == isBlackPlayer || !state.isBlackTurn() == !isBlackPlayer){
				int maxEval = Integer.MIN_VALUE;
				ArrayList<OthelloMove> moves = getValidMoves(state);

				for(OthelloMove curMove : moves){
					OthelloGameState stateClone = (OthelloGameState)state.clone();
					int curEval = search(stateClone, depth - 1);
					maxEval = Math.max(curEval, maxEval);
				}
				return maxEval;
			}
			else{
				int minEval = Integer.MAX_VALUE;
				ArrayList<OthelloMove> moves = getValidMoves(state);

				for(OthelloMove curMove : moves){
					OthelloGameState stateClone = (OthelloGameState)state.clone();
					int curEval = search(stateClone, depth - 1);
					minEval = Math.max(curEval, minEval);
				}
				return minEval;
			}
		}
	}
	@Override
	public OthelloMove chooseMove(OthelloGameState state) {
		// TODO Auto-generated method stub

		isBlackPlayer = state.isBlackTurn();
		ArrayList<OthelloMove> moves = getValidMoves(state);
		int bestEval = Integer.MIN_VALUE;
		OthelloMove bestMove = null;
		for(OthelloMove thisMove : moves){
			OthelloGameState stateClone = (OthelloGameState)state.clone();
			int curEval = search(stateClone, DEPTH);
			bestEval = Math.max(curEval, bestEval);
			if(bestEval == curEval){
				bestMove = thisMove;
			}
		}



		return bestMove ;
	}

}
